#include "backtest/backtest_engine.h"
#include "strategy/strategy.h"
#include "risk/risk.h"
#include "core/monitor.h"
#include "market_data/market_data_types.h"
#include <nlohmann/json.hpp>
#include <spdlog/spdlog.h>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <atomic>
#include <chrono>

// 性能统计数据结构
struct PerformanceStats {
    std::atomic<uint64_t> market_data_processed{0};
    std::atomic<uint64_t> orders_processed{0};
    std::atomic<uint64_t> positions_updated{0};
    std::chrono::microseconds total_time{0};
    std::chrono::microseconds market_data_time{0};
    std::chrono::microseconds order_time{0};
    std::chrono::microseconds position_time{0};
    
    void reset() {
        market_data_processed = 0;
        orders_processed = 0;
        positions_updated = 0;
        total_time = std::chrono::microseconds{0};
        market_data_time = std::chrono::microseconds{0};
        order_time = std::chrono::microseconds{0};
        position_time = std::chrono::microseconds{0};
    }
};

namespace hft {

BacktestEngine::BacktestEngine() : running_(false) {
    stats_.reset();
}

const PerformanceStats& BacktestEngine::getStats() const {
    return stats_;
}

BacktestEngine::~BacktestEngine() {
    stop();
}

bool BacktestEngine::init(const nlohmann::json& config) {
    try {
        config_ = config;

        // 初始化策略
        if (!initStrategy()) {
            spdlog::error("Failed to initialize strategy");
            return false;
        }

        // 初始化风险
        if (!initRisk()) {
            spdlog::error("Failed to initialize risk manager");
            return false;
        }

        // 初始化监控
        if (!initMonitor()) {
            spdlog::error("Failed to initialize monitor");
            return false;
        }

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize backtest engine: {}", e.what());
        return false;
    }
}

bool BacktestEngine::loadData(const std::string& data_path) {
    try {
        spdlog::info("Loading market data from: {}", data_path);
        
        // 使用内存映射文件提高读取性能
        std::ifstream file(data_path, std::ios::ate);
        if (!file.is_open()) {
            spdlog::error("Failed to open data file: {}", data_path);
            return false;
        }

        // 预分配内存
        size_t file_size = file.tellg();
        file.seekg(0);
        market_data_.reserve(file_size / 100); // 估计每行约100字节

        // 批量读取和处理
        std::string line;
        line.reserve(256); // 预分配行缓冲区
        size_t line_count = 0;
        std::vector<MarketDataMessage> batch;
        batch.reserve(1000); // 批量处理1000条记录

        auto processBatch = [this](auto& batch) {
            market_data_.insert(market_data_.end(), 
                              std::make_move_iterator(batch.begin()),
                              std::make_move_iterator(batch.end()));
            batch.clear();
        };

        while (std::getline(file, line)) {
            MarketDataMessage data;
            std::istringstream iss(line);
            if (iss >> data.symbol
                   >> data.last_price
                   >> data.volume
                   >> data.turnover
                   >> data.open_interest
                   >> data.bid_price
                   >> data.bid_volume
                   >> data.ask_price
                   >> data.ask_volume) {
                batch.push_back(std::move(data));
                if (batch.size() >= 1000) {
                    processBatch(batch);
                }
                line_count++;
            } else {
                spdlog::warn("Invalid data format at line {}", line_count + 1);
            }
        }

        // 处理剩余批次
        if (!batch.empty()) {
            processBatch(batch);
        }

        spdlog::info("Successfully loaded {} market data records", market_data_.size());
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to load data: {} (Error: {})", data_path, e.what());
        return false;
    }
}

BacktestResult BacktestEngine::run() {
    try {
        running_ = true;
        stats_.reset();
        const size_t total_records = market_data_.size();
        spdlog::info("Starting backtest with {} market records", total_records);
        
        auto start_time = std::chrono::steady_clock::now();

        // 进度报告变量
        size_t processed = 0;
        auto last_report = std::chrono::steady_clock::now();
        const auto report_interval = std::chrono::seconds(5);

        // 并行处理市场数据
        #pragma omp parallel for schedule(dynamic, 100)
        for (size_t i = 0; i < market_data_.size(); ++i) {
            if (!running_) continue;

            const auto& data = market_data_[i];
            
            // 处理行情数据
            processMarketData(data);

            // 批量处理订单
            #pragma omp critical
            {
                for (const auto& [symbol, orders] : active_orders_) {
                    for (const auto& order : orders) {
                        processOrder(order);
                    }
                }

                // 更新持仓和账户
                for (const auto& [symbol, position] : positions_) {
                    updatePosition(position);
                }
                updateAccount(account_);
            }

            // 进度报告
            #pragma omp atomic
            ++processed;

            auto now = std::chrono::steady_clock::now();
            if (now - last_report > report_interval) {
                #pragma omp critical
                {
                    if (now - last_report > report_interval) {
                        double progress = 100.0 * processed / total_records;
                        spdlog::info("Backtest progress: {:.1f}% ({} of {})", 
                                    progress, processed, total_records);
                        last_report = now;
                    }
                }
            }
        }

        if (!running_) {
            spdlog::warn("Backtest was stopped prematurely");
        } else {
            // 计算回测指标
            calculateMetrics();
            
            // 计算总耗时
            auto end_time = std::chrono::steady_clock::now();
            stats_.total_time = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
            
            // 输出性能报告
            double total_sec = stats_.total_time.count() / 1000000.0;
            double market_rate = stats_.market_data_processed / total_sec;
            double order_rate = stats_.orders_processed / total_sec;
            
            spdlog::info("Backtest completed successfully");
            spdlog::info("Performance Report:");
            spdlog::info("  Total time: {:.3f} seconds", total_sec);
            spdlog::info("  Market data processed: {} ({:.1f} msg/sec)", 
                        stats_.market_data_processed, market_rate);
            spdlog::info("  Orders processed: {} ({:.1f} orders/sec)", 
                        stats_.orders_processed, order_rate);
            spdlog::info("  Positions updated: {}", stats_.positions_updated);
        }

        return result_;
    } catch (const std::exception& e) {
        spdlog::error("Backtest failed: {}", e.what());
        running_ = false;
        return result_;
    }
}

bool BacktestEngine::initStrategy() {
    try {
        const auto& strategy_config = config_["trading"]["strategy"];
        std::string strategy_name = strategy_config["name"].get<std::string>();
        strategy_ = StrategyFactory::createStrategy(strategy_name);
        if (!strategy_) {
            spdlog::error("Failed to create strategy: {}", strategy_name);
            return false;
        }
        return strategy_->init(config_);
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize strategy: {}", e.what());
        return false;
    }
}

bool BacktestEngine::initRisk() {
    try {
        return RiskManager::getInstance().init(config_);
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize risk manager: {}", e.what());
        return false;
    }
}

bool BacktestEngine::initMonitor() {
    try {
        const auto& monitor_config = config_["trading"]["performance"];
        std::string monitor_type = monitor_config["export"]["type"].get<std::string>();
        auto monitor = MonitorFactory::createMonitor(monitor_type);
        if (!monitor) {
            spdlog::error("Failed to create monitor: {}", monitor_type);
            return false;
        }
        return monitor->init(config_);
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize monitor: {}", e.what());
        return false;
    }
}

void BacktestEngine::processMarketData(const MarketDataMessage& data) {
    auto start = std::chrono::steady_clock::now();
    // 更新策略
    strategy_->onMarketData(data);

    // 更新风控
    RiskManager::getInstance().onMarketData(data);

    auto end = std::chrono::steady_clock::now();
    stats_.market_data_time += std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    stats_.market_data_processed++;
}

void BacktestEngine::processOrder(const Order& order) {
    auto start = std::chrono::steady_clock::now();
    
    // 检查风险
    if (!RiskManager::getInstance().checkOrder(order)) {
        spdlog::warn("Order rejected by risk manager: {}", order.order_id);
        return;
    }

    // 模拟订单执行
    Trade trade;
    trade.trade_id = "trade_" + order.order_id;
    trade.order_id = order.order_id;
    trade.symbol = order.symbol;
    trade.direction = order.direction;
    trade.offset = order.offset;
    trade.price = order.price;
    trade.volume = order.volume;
    trade.timestamp = std::chrono::system_clock::now();

    // 更新策略
    strategy_->onTrade(trade);

    // 更新风控
    RiskManager::getInstance().onTrade(trade);

    // 记录交易
    trades_.push_back(trade);

    auto end = std::chrono::steady_clock::now();
    stats_.order_time += std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    stats_.orders_processed++;
}

void BacktestEngine::updatePosition(const Position& position) {
    auto start = std::chrono::steady_clock::now();
    
    // 更新策略
    strategy_->onPosition(position);

    // 更新风控
    RiskManager::getInstance().onPosition(position);

    auto end = std::chrono::steady_clock::now();
    stats_.position_time += std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    stats_.positions_updated++;
}

void BacktestEngine::printStatistics() const {
    spdlog::info("===== Backtest Performance Statistics =====");
    spdlog::info("Market Data Processing:");
    spdlog::info("  Total processed: {}", stats_.market_data_processed);
    spdlog::info("  Total time: {} us", stats_.market_data_time.count());
    spdlog::info("  Avg time: {:.2f} us", 
        stats_.market_data_processed > 0 
        ? static_cast<double>(stats_.market_data_time.count()) / stats_.market_data_processed 
        : 0.0);

    spdlog::info("Order Processing:");
    spdlog::info("  Total processed: {}", stats_.orders_processed);
    spdlog::info("  Total time: {} us", stats_.order_time.count());
    spdlog::info("  Avg time: {:.2f} us",
        stats_.orders_processed > 0
        ? static_cast<double>(stats_.order_time.count()) / stats_.orders_processed
        : 0.0);

    spdlog::info("Position Updates:");
    spdlog::info("  Total updated: {}", stats_.positions_updated);
    spdlog::info("  Total time: {} us", stats_.position_time.count());
    spdlog::info("  Avg time: {:.2f} us",
        stats_.positions_updated > 0
        ? static_cast<double>(stats_.position_time.count()) / stats_.positions_updated
        : 0.0);
}

void BacktestEngine::updateAccount(const Account& account) {
    // 更新策略
    strategy_->onAccount(account);

    // 更新风控
    RiskManager::getInstance().onAccount(account);
}

void BacktestEngine::calculateMetrics() {
    // 计算收益
    calculateReturns();

    // 计算回撤
    calculateDrawdowns();

    // 计算夏普比率
    result_.sharpe_ratio = calculateSharpeRatio();

    // 计算胜率
    result_.win_rate = calculateWinRate();

    // 计算盈亏比
    // 计算盈亏�?
    result_.profit_factor = calculateProfitFactor();

    // 计算最大连续盈亏次�?
    calculateConsecutiveWinsLosses();
}

void BacktestEngine::calculateReturns() {
    if (trades_.empty()) return;

    // 计算每笔交易的收益率
    std::vector<double> trade_returns;
    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }
        trade_returns.push_back(pnl);
    }

    // 计算总收益率
    result_.total_return = std::accumulate(trade_returns.begin(), trade_returns.end(), 0.0);

    // 计算年化收益�?
    double days = (trades_.back().timestamp - trades_.front().timestamp).count() / (24.0 * 3600.0 * 1e9);
    result_.annual_return = result_.total_return / days * 252.0;

    // 保存收益率序�?
    result_.returns = trade_returns;
}

void BacktestEngine::calculateDrawdowns() {
    if (result_.returns.empty()) return;

    // 计算权益曲线
    std::vector<double> equity;
    double current_equity = 0.0;
    for (double ret : result_.returns) {
        current_equity += ret;
        equity.push_back(current_equity);
    }

    // 计算回撤
    std::vector<double> drawdowns;
    double peak = equity[0];
    for (double e : equity) {
        if (e > peak) {
            peak = e;
        }
        double drawdown = (peak - e) / peak;
        drawdowns.push_back(drawdown);
    }

    // 计算最大回�?
    result_.max_drawdown = *std::max_element(drawdowns.begin(), drawdowns.end());

    // 保存回撤序列
    result_.drawdowns = drawdowns;
}

double BacktestEngine::calculateSharpeRatio() {
    if (result_.returns.empty()) return 0.0;

    // 计算收益率均值和标准�?
    double mean = std::accumulate(result_.returns.begin(), result_.returns.end(), 0.0) / result_.returns.size();
    double variance = 0.0;
    for (double ret : result_.returns) {
        variance += (ret - mean) * (ret - mean);
    }
    variance /= result_.returns.size();
    double std_dev = std::sqrt(variance);

    // 计算夏普比率
    return mean / std_dev * std::sqrt(252.0);
}

double BacktestEngine::calculateWinRate() {
    if (trades_.empty()) return 0.0;

    // 计算盈利交易次数
    int winning_trades = 0;
    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }
        if (pnl > 0) {
            winning_trades++;
        }
    }

    // 计算胜率
    return static_cast<double>(winning_trades) / trades_.size();
}

double BacktestEngine::calculateProfitFactor() {
    if (trades_.empty()) return 0.0;

    // 计算总盈利和总亏�?
    double total_profit = 0.0;
    double total_loss = 0.0;
    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }
        if (pnl > 0) {
            total_profit += pnl;
        } else {
            total_loss += std::abs(pnl);
        }
    }

    // 计算盈亏�?
    return total_loss == 0.0 ? 0.0 : total_profit / total_loss;
}

void BacktestEngine::calculateConsecutiveWinsLosses() {
    if (trades_.empty()) return;

    // 计算连续盈亏次数
    int current_wins = 0;
    int current_losses = 0;
    int max_wins = 0;
    int max_losses = 0;

    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }

        if (pnl > 0) {
            current_wins++;
            current_losses = 0;
            max_wins = std::max(max_wins, current_wins);
        } else {
            current_losses++;
            current_wins = 0;
            max_losses = std::max(max_losses, current_losses);
        }
    }

    result_.max_consecutive_wins = max_wins;
    result_.max_consecutive_losses = max_losses;
}

} // namespace hft 